package com.keba.lamp.common.utils;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.poi.word.Word07Writer;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.apache.poi.util.Units;
import org.apache.poi.wp.usermodel.HeaderFooterType;
import org.apache.poi.xwpf.model.XWPFHeaderFooterPolicy;
import org.apache.poi.xwpf.usermodel.ParagraphAlignment;
import org.apache.poi.xwpf.usermodel.TableWidthType;
import org.apache.poi.xwpf.usermodel.XWPFDocument;
import org.apache.poi.xwpf.usermodel.XWPFFooter;
import org.apache.poi.xwpf.usermodel.XWPFParagraph;
import org.apache.poi.xwpf.usermodel.XWPFRun;
import org.apache.poi.xwpf.usermodel.XWPFTable;
import org.apache.poi.xwpf.usermodel.XWPFTableCell;
import org.apache.poi.xwpf.usermodel.XWPFTableRow;
import org.apache.xmlbeans.impl.xb.xmlschema.SpaceAttribute;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTBody;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTBorder;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTFldChar;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTInd;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTPPr;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTPageMar;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTSectPr;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTTblBorders;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTTcMar;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTTcPr;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTText;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.STBorder;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.STFldCharType;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.STHdrFtr;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.STMerge;

import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.OutputStream;
import java.math.BigInteger;
import java.net.URL;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
import java.util.concurrent.LinkedBlockingDeque;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

@Slf4j
public class WordUtil {

    private final static Charset charset = Charset.forName("GBK");
    final static String[] colWidth = {"12%", "24%", "40%", "12%", "12%"};
    //核心线程数核心线程默认会一直存在
    public static int corePoolSize = 10;

    //最大线程数
    public static int maximumPoolSize = 50;

    //非核心线程的线程存活时间
    public static int keepAliveTime = 10;
    public static void html2Word(String htmlContent, OutputStream outputStream) throws Exception {

    }


    public static void image2Word(List<String> imageUrlList, OutputStream outputStream) throws Exception {
        /************************线程池下载图片***********************/
        ThreadPoolExecutor executorService = buildThreadPool();
        List<Future<ImageResult>> futures = new ArrayList<>();
        for (int i = 0 ; i < imageUrlList.size(); i++) {
            final int index = i;
            final String imageUrl = imageUrlList.get(i);
            Future<ImageResult> submit = executorService.submit(() -> {
                try {
                    long begin = System.currentTimeMillis();
                    log.info("下载图片开始:{}", imageUrl);
                    BufferedImage image = ImageIO.read(new URL(imageUrl));
                    log.info("下载图片结束:{}, 耗时:{}", imageUrl, System.currentTimeMillis() - begin);
                    ImageResult imageResult = new ImageResult();
                    imageResult.setIndex(index);
                    imageResult.setImage(image);
                    return imageResult;
                } catch (Exception e) {
                    log.error("图片下载失败", e);
                    return null;
                }
            });
            futures.add(submit);
        }
        executorService.shutdown();
        try {
            if (!executorService.awaitTermination(30, TimeUnit.SECONDS)) {
                executorService.shutdownNow();
            }
        } catch (InterruptedException e) {
            executorService.shutdownNow();
            Thread.currentThread().interrupt();
            throw new RuntimeException("图片下载失败");
        }
        List<BufferedImage> imageList = new ArrayList<>();
        for (Future<ImageResult> future : futures) {
            try {
                ImageResult imageResult = future.get();
                if (imageResult == null) {
                    throw new RuntimeException("图片下载失败");
                }
                imageList.add(imageResult.getIndex(), imageResult.getImage());
            } catch (ExecutionException e) {
                log.error("图片下载失败:", e);
                throw new RuntimeException("图片下载失败");
            } catch (InterruptedException e) {
                log.error("图片下载失败:", e);
                throw new RuntimeException("图片下载失败");
            }
        }
        /************************开始生成word文档***********************/

        try {
            Word07Writer writer = cn.hutool.poi.word.WordUtil.getWriter();
            XWPFDocument doc = writer.getDoc();
            CTBody body = doc.getDocument().getBody();
            CTSectPr sectPr = body.isSetSectPr() ? body.getSectPr() : body.addNewSectPr();
            CTPageMar ctPageMar = sectPr.isSetPgMar() ? sectPr.getPgMar() : sectPr.addNewPgMar();
            // 创建页脚
            createPageNumberFooter(doc, sectPr);
            setPageMargin(ctPageMar);

            Font titleFont = new Font("宋体", Font.BOLD, 18);
            Font normalBoldFont = new Font("宋体", Font.BOLD, 12);
            Font normalFont = new Font("宋体", Font.TRUETYPE_FONT, 12);
            for (int i = 0; i < imageList.size(); i++) {
                BufferedImage image = imageList.get(i);
                XWPFParagraph paragraph = doc.createParagraph();
                paragraph.setAlignment(ParagraphAlignment.CENTER);
                XWPFRun run = paragraph.createRun();
                int originalType = image.getType();
                ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
                ImageIO.write(image, "png", byteArrayOutputStream);
                ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(byteArrayOutputStream.toByteArray());
                run.addPicture(byteArrayInputStream, XWPFDocument.PICTURE_TYPE_JPEG, "image.png", Units.toEMU(image.getWidth()), Units.toEMU(image.getHeight()));
//                run.addPicture(byteArrayInputStream, XWPFDocument.PICTURE_TYPE_JPEG, "image.jpg", null, null);
            }
            doc.write(outputStream);
        } catch (Exception e) {
            log.error("生成word失败", e);
        }
    }

    /**
     * 设置页面边距
     * @param ctPageMar
     */
    private static void setPageMargin(CTPageMar ctPageMar) {
        //1cm = 567缇
        //31.8mm
        ctPageMar.setLeft(BigInteger.valueOf(1800));  // 磅转换为缇（1磅=20缇）
        //25.4mm
        ctPageMar.setTop(BigInteger.valueOf(1440));
        //31.8mm
        ctPageMar.setRight(BigInteger.valueOf(1800));
        //25.4mm
        ctPageMar.setBottom(BigInteger.valueOf(1440));
    }

    /**
     * 定义一个线程池
     *
     * @return
     */
    public static ThreadPoolExecutor buildThreadPool() {
        ThreadPoolExecutor executor = new ThreadPoolExecutor(
                corePoolSize,
                maximumPoolSize,
                keepAliveTime, TimeUnit.SECONDS,
                new LinkedBlockingDeque<>(200)); //有界队列，容量200;
        return executor;
    }

    public static void convert2Word(List<String> plaintffList,
                                    List<String> plaintfffAgentList,
                                    List<String> defendantList,
                                    List<String> defendantAgentList,
                                    LinkedHashMap<String, String> linkedHashMap,
                                    OutputStream outputStream) throws Exception {
        Word07Writer writer = cn.hutool.poi.word.WordUtil.getWriter();
        XWPFDocument doc = writer.getDoc();
        CTBody body = doc.getDocument().getBody();
        CTSectPr sectPr = body.isSetSectPr() ? body.getSectPr() : body.addNewSectPr();
        CTPageMar ctPageMar = sectPr.isSetPgMar() ? sectPr.getPgMar() : sectPr.addNewPgMar();
        // 创建页脚
        createPageNumberFooter(doc, sectPr);
        //1cm = 567缇
        //31.8mm
        setPageMargin(ctPageMar);
        Font titleFont = new Font("宋体", Font.BOLD, 18);
        Font normalBoldFont = new Font("宋体", Font.BOLD, 12);
        Font normalFont = new Font("宋体", Font.TRUETYPE_FONT, 12);
        XWPFParagraph titleParagraph = doc.createParagraph();
        titleParagraph.setAlignment(ParagraphAlignment.CENTER);
        XWPFRun titleRun = titleParagraph.createRun();
        titleRun.setText("民事起诉状");
        titleRun.setBold(true);
        titleRun.setFontSize(18L);
        titleRun.setFontFamily("宋体");

        //writer.addText(ParagraphAlignment.CENTER, titleFont, "起诉书");
        writer.addText(normalFont, "");

        // 设置首行缩进为 1 cm
        //paragraph.setIndentationFirstLine(720); // 1 cm = 720 twips
        if (plaintffList.size() > 1) {
            for (int i = 0; i < plaintffList.size(); i++) {
                XWPFParagraph paragraph = doc.createParagraph();
                paragraph.setFirstLineIndent(420);
                XWPFRun run = paragraph.createRun();
                run.setText("原告" + (i + 1) + "：");
                run.setBold(true);
                run.setFontSize(12L);
                run.setFontFamily("宋体");
                XWPFRun run1 = paragraph.createRun();
                String plaintffName = plaintffList.get(i);
                run1.setText(StringUtils.isBlank(plaintffName) ? "" : plaintffName);
                run1.setFontSize(12L);
                run1.setFontFamily("宋体");
            }
        } else {
            XWPFParagraph paragraph = doc.createParagraph();
            paragraph.setFirstLineIndent(420);
            XWPFRun run = paragraph.createRun();
            run.setText("原告：");
            run.setBold(true);
            run.setFontSize(12L);
            run.setFontFamily("宋体");
            XWPFRun run1 = paragraph.createRun();
            String plaintffName = plaintffList.get(0);
            run1.setText(StringUtils.isBlank(plaintffName) ? "" : plaintffName);
            run1.setFontSize(12L);
            run1.setFontFamily("宋体");
        }
        writer.addText(normalFont, "");
        //代理人
        if (CollectionUtil.isNotEmpty(plaintfffAgentList)) {
            if (plaintfffAgentList.size() > 1) {
                for (int i = 0; i < plaintfffAgentList.size(); i++) {
                    XWPFParagraph paragraph = doc.createParagraph();
                    paragraph.setFirstLineIndent(420);
                    XWPFRun run = paragraph.createRun();
                    run.setText("委托代理人" + (i + 1) + "：");
                    run.setBold(true);
                    run.setFontSize(12L);
                    run.setFontFamily("宋体");
                    XWPFRun run1 = paragraph.createRun();
                    String agentName = plaintfffAgentList.get(i);
                    run1.setText(StringUtils.isBlank(agentName) ? "" : agentName);
                    run1.setFontSize(12L);
                    run1.setFontFamily("宋体");
                }
            } else {
                XWPFParagraph paragraph = doc.createParagraph();
                paragraph.setFirstLineIndent(420);
                XWPFRun run = paragraph.createRun();
                run.setText("委托代理人：");
                run.setBold(true);
                run.setFontSize(12L);
                run.setFontFamily("宋体");
                XWPFRun run1 = paragraph.createRun();
                String plaintffName = plaintfffAgentList.get(0);
                run1.setText(StringUtils.isBlank(plaintffName) ? "" : plaintffName);
                run1.setFontSize(12L);
                run1.setFontFamily("宋体");
            }
            writer.addText(normalFont, "");
        }

        if (defendantList.size() > 1) {
            for (int i = 0; i < defendantList.size(); i++) {
                XWPFParagraph paragraph = doc.createParagraph();
                paragraph.setFirstLineIndent(420);
                XWPFRun run = paragraph.createRun();
                run.setText("被告" + (i + 1) + "：");
                run.setBold(true);
                run.setFontSize(12L);
                run.setFontFamily("宋体");
                XWPFRun run1 = paragraph.createRun();
                String defendantName = defendantList.get(i);
                run1.setText(StringUtils.isBlank(defendantName) ? "" : defendantName);
                run1.setFontSize(12L);
                run1.setFontFamily("宋体");
            }
        } else {
            XWPFParagraph paragraph = doc.createParagraph();
            paragraph.setFirstLineIndent(420);
            XWPFRun run = paragraph.createRun();
            run.setText("被告：");
            run.setBold(true);
            run.setFontSize(12L);
            run.setFontFamily("宋体");
            XWPFRun run1 = paragraph.createRun();
            String defendantName = defendantList.get(0);
            run1.setText(StringUtils.isBlank(defendantName) ? "" : defendantName);
            run1.setFontSize(12L);
            run1.setFontFamily("宋体");
        }
        writer.addText(normalFont, "");
        //代理人
        if (CollectionUtil.isNotEmpty(defendantAgentList)) {
            if (defendantAgentList.size() > 1) {
                for (int i = 0; i < defendantAgentList.size(); i++) {
                    XWPFParagraph paragraph = doc.createParagraph();
                    paragraph.setFirstLineIndent(420);
                    XWPFRun run = paragraph.createRun();
                    run.setText("委托代理人" + (i + 1) + "：");
                    run.setBold(true);
                    run.setFontSize(12L);
                    run.setFontFamily("宋体");
                    XWPFRun run1 = paragraph.createRun();
                    String agentName = defendantAgentList.get(i);
                    run1.setText(StringUtils.isBlank(agentName) ? "" : agentName);
                    run1.setFontSize(12L);
                    run1.setFontFamily("宋体");
                }
            } else {
                XWPFParagraph paragraph = doc.createParagraph();
                paragraph.setFirstLineIndent(420);
                XWPFRun run = paragraph.createRun();
                run.setText("委托代理人：");
                run.setBold(true);
                run.setFontSize(12L);
                run.setFontFamily("宋体");
                XWPFRun run1 = paragraph.createRun();
                String plaintffName = defendantAgentList.get(0);
                run1.setText(StringUtils.isBlank(plaintffName) ? "" : plaintffName);
                run1.setFontSize(12L);
                run1.setFontFamily("宋体");
            }
            writer.addText(normalFont, "");
        }

        //3、起诉状内容 小四
        for (String key : linkedHashMap.keySet()) {
            if (!"法院".equals(key)) {
                XWPFParagraph paragraph1 = doc.createParagraph();
                XWPFRun run1 = paragraph1.createRun();
                run1.setText(key + "：");
                run1.setBold(true);
                run1.setFontSize(12L);
                run1.setFontFamily("宋体");

                String value = linkedHashMap.get(key);
                String[] strings = value.split("\n");
                for (String s : strings) {
                    XWPFParagraph paragraph2 = doc.createParagraph();
                    paragraph2.setFirstLineIndent(420);
                    XWPFRun run2 = paragraph2.createRun();
                    run2.setText(s);
                    run2.setFontSize(12L);
                    run2.setFontFamily("宋体");
                }
            } else {
                XWPFParagraph paragraph1 = doc.createParagraph();
                paragraph1.setFirstLineIndent(420);
                XWPFRun run1 = paragraph1.createRun();
                run1.setText("此致");
                run1.setBold(true);
                run1.setFontSize(12L);
                run1.setFontFamily("宋体");

                XWPFParagraph paragraph2 = doc.createParagraph();
                paragraph2.setFirstLineIndent(420);
                String value = linkedHashMap.get(key);
                XWPFRun run2 = paragraph2.createRun();
                run2.setText(value);
                run2.setFontSize(12L);
                run2.setFontFamily("宋体");

            }
            //空一行
            writer.addText(normalFont, "");
        }

        //4、页尾 签名 小四
        XWPFParagraph endParagraph = doc.createParagraph();
        endParagraph.setAlignment(ParagraphAlignment.RIGHT);
        // 获取段落属性
        CTPPr pr = endParagraph.getCTP().addNewPPr();
        CTInd ind = pr.addNewInd();
        // 设置右缩进
        ind.setRight(BigInteger.valueOf(840)); // 840缇
        XWPFRun endRun = endParagraph.createRun();
        endRun.setText("起诉人（签名）：        ");
        endRun.setFontSize(12L);
        endRun.setFontFamily("宋体");
        //空一行
        writer.addText(normalFont, "");
        //5、页尾 日期 小四
        XWPFParagraph dateParagraph = doc.createParagraph();
        dateParagraph.setAlignment(ParagraphAlignment.END);
        XWPFRun dateRun = dateParagraph.createRun();
        dateRun.setText("年    月    日");
        dateRun.setFontSize(12L);
        dateRun.setFontFamily("宋体");
        doc.write(outputStream);
    }

    @Data
    public static class ImageResult {
        private Integer index;
        private BufferedImage image;
    }

    public static void create(List<String> plaintffList,
                              List<String> defendantList,
                              String htmlContent,
                              OutputStream outputStream) throws Exception {
        Word07Writer writer = cn.hutool.poi.word.WordUtil.getWriter();
        XWPFDocument doc = writer.getDoc();

        CTBody body = doc.getDocument().getBody();
        CTSectPr sectPr = body.isSetSectPr() ? body.getSectPr() : body.addNewSectPr();
        CTPageMar ctPageMar = sectPr.isSetPgMar() ? sectPr.getPgMar() : sectPr.addNewPgMar();
        // 创建页脚
        createPageNumberFooter(doc, sectPr);
        //1cm = 567缇
        //31.8mm
        setPageMargin(ctPageMar);
        Font titleFont = new Font("宋体", Font.BOLD, 18);
        Font normalBoldFont = new Font("宋体", Font.BOLD, 12);
        Font normalFont = new Font("宋体", Font.TRUETYPE_FONT, 12);
        XWPFParagraph titleParagraph = doc.createParagraph();
        titleParagraph.setAlignment(ParagraphAlignment.CENTER);
        XWPFRun titleRun = titleParagraph.createRun();
        titleRun.setText("证据目录");
        titleRun.setBold(true);
        titleRun.setFontSize(18L);
        titleRun.setFontFamily("宋体");

        //writer.addText(ParagraphAlignment.CENTER, titleFont, "起诉书");
        writer.addText(normalFont, "");

        // 设置首行缩进为 1 cm
        //paragraph.setIndentationFirstLine(720); // 1 cm = 720 twips
        if (plaintffList.size() > 1) {
            for (int i = 0; i < plaintffList.size(); i++) {
                XWPFParagraph paragraph = doc.createParagraph();
                XWPFRun run = paragraph.createRun();
                run.setText("原告" + (i + 1) + "：");
                run.setFontSize(12L);
                run.setFontFamily("宋体");
                XWPFRun run1 = paragraph.createRun();
                run1.setText(plaintffList.get(i));
                run1.setFontSize(12L);
                run1.setFontFamily("宋体");
            }
        } else {
            XWPFParagraph paragraph = doc.createParagraph();
            XWPFRun run = paragraph.createRun();
            run.setText("原告：");
            run.setFontSize(12L);
            run.setFontFamily("宋体");
            XWPFRun run1 = paragraph.createRun();
            run1.setText(plaintffList.get(0));
            run1.setFontSize(12L);
            run1.setFontFamily("宋体");
        }
        if (defendantList.size() > 1) {
            for (int i = 0; i < defendantList.size(); i++) {
                XWPFParagraph paragraph = doc.createParagraph();
                XWPFRun run = paragraph.createRun();
                run.setText("被告" + (i + 1) + "：");
                run.setFontSize(12L);
                run.setFontFamily("宋体");
                XWPFRun run1 = paragraph.createRun();
                run1.setText(defendantList.get(i));
                run1.setFontSize(12L);
                run1.setFontFamily("宋体");
            }
        } else {
            XWPFParagraph paragraph = doc.createParagraph();
            XWPFRun run = paragraph.createRun();
            run.setText("被告：");
            run.setFontSize(12L);
            run.setFontFamily("宋体");
            XWPFRun run1 = paragraph.createRun();
            run1.setText(defendantList.get(0));
            run1.setFontSize(12L);
            run1.setFontFamily("宋体");
        }
        writer.addText(normalFont, "");

        // 将HTML内容转换为Word文档
        ByteArrayInputStream inputStream = new ByteArrayInputStream(htmlContent.getBytes(StandardCharsets.UTF_8));
        // 读取HTML内容
        Document htmlDoc = Jsoup.parse(inputStream, "UTF-8", "");
        // 提取所有表格
        Elements tables = htmlDoc.select("table");
        log.info("生成word原始html内容：{}", tables.html());
        convertTableToWord(tables.get(0), doc);
        writer.addText(normalFont, "");
        //3、备注
        XWPFParagraph remarkParagraph = doc.createParagraph();
        XWPFRun remarkRun = remarkParagraph.createRun();
        remarkRun.setText("注：以上均为复印件，原件待开庭时提供");
        remarkRun.setFontSize(12L);
        remarkRun.setFontFamily("宋体");
        writer.addText(normalFont, "");
        writer.addText(normalFont, "");
        writer.addText(normalFont, "");

        //4、页尾 签名 小四
        XWPFParagraph endParagraph = doc.createParagraph();
        endParagraph.setAlignment(ParagraphAlignment.RIGHT);
        // 获取段落属性
        CTPPr pr = endParagraph.getCTP().addNewPPr();
        CTInd ind = pr.addNewInd();
        // 设置右缩进
        ind.setRight(BigInteger.valueOf(840)); // 840缇
        XWPFRun endRun = endParagraph.createRun();
        endRun.setText("提交人：");
        endRun.setFontSize(12L);
        endRun.setFontFamily("宋体");
        //空一行
        writer.addText(normalFont, "");
        //5、页尾 日期 小四
        XWPFParagraph dateParagraph = doc.createParagraph();
        dateParagraph.setAlignment(ParagraphAlignment.END);
        XWPFRun dateRun = dateParagraph.createRun();
        dateRun.setText("提交时间：    年    月    日");
        dateRun.setFontSize(12L);
        dateRun.setFontFamily("宋体");

        doc.write(outputStream);
    }
    private static void convertTableToWord(Element htmlTable, XWPFDocument document) {
        // 解析表格样式
        Map<String, String> tableStyles = parseStyles(htmlTable);

        // 计算表格的实际列数
        int maxCols = calculateMaxColumns(htmlTable);

        // 创建Word表格
        XWPFTable table = document.createTable(1, maxCols);
        table.setWidth(100);
        table.setWidthType(TableWidthType.PCT);
        // 初始化单元格映射，用于处理合并单元格
        Map<Integer, Integer> cellRowSpan = new HashMap<>();

        // 解析列宽设置
        List<ColumnWidth> columnWidths = parseColumnWidths(htmlTable, maxCols);

        // 应用列宽设置
        applyColumnWidths(table, columnWidths);

        // 处理表格行
        Elements rows = htmlTable.select("tr");
        for (int rowIdx = 0; rowIdx < rows.size(); rowIdx++) {
            Element htmlRow = rows.get(rowIdx);
            XWPFTableRow tableRow = rowIdx == 0 ? table.getRow(0) : table.createRow();

            // 处理行样式
            Map<String, String> rowStyles = parseStyles(htmlRow);
            applyRowStyle(tableRow, rowStyles);

            // 当前列索引
            int colIdx = 0;

            // 处理行中的单元格
            Elements cells = htmlRow.select("td, th");
            for (Element htmlCell : cells) {
                // 跳过已经被合并的单元格位置
                while (cellRowSpan.containsKey(colIdx) && cellRowSpan.get(colIdx) > 0) {
                    colIdx++;
                }

                // 获取单元格属性
                int colspan = getIntAttribute(htmlCell, "colspan", 1);
                int rowspan = getIntAttribute(htmlCell, "rowspan", 1);

                // 确保表格有足够的列
                while (tableRow.getTableCells().size() <= colIdx + colspan - 1) {
                    tableRow.addNewTableCell();
                }

                // 获取当前单元格
                XWPFTableCell tableCell = tableRow.getCell(colIdx);
                tableCell.setWidth(String.valueOf(columnWidths.get(colIdx).width));
                tableCell.setWidthType(columnWidths.get(colIdx).type);

                // 处理单元格样式和内容
                processCell(htmlCell, tableCell, colspan, rowspan);

                // 设置单元格的合并属性
                setCellMerging(table, rowIdx, colIdx, rowspan, colspan);

                // 更新行跨度映射
                if (rowspan > 1) {
                    cellRowSpan.put(colIdx, rowspan - 1);
                }

                // 移动到下一列
                colIdx += colspan;
            }

            // 更新行跨度映射
            Map<Integer, Integer> newCellRowSpan = new HashMap<>();
            for (Map.Entry<Integer, Integer> entry : cellRowSpan.entrySet()) {
                int remainingSpan = entry.getValue() - 1;
                if (remainingSpan > 0) {
                    newCellRowSpan.put(entry.getKey(), remainingSpan);
                }
            }
            cellRowSpan = newCellRowSpan;
        }

        // 应用表格整体样式
        applyTableStyle(table, tableStyles);
    }

    private static int calculateMaxColumns(Element htmlTable) {
        int maxCols = 0;

        // 遍历所有行，计算最大列数（考虑colspan）
        Elements rows = htmlTable.select("tr");
        for (Element row : rows) {
            int currentCols = 0;
            Elements cells = row.select("td, th");
            for (Element cell : cells) {
                currentCols += getIntAttribute(cell, "colspan", 1);
            }
            if (currentCols > maxCols) {
                maxCols = currentCols;
            }
        }

        return maxCols;
    }

    private static List<ColumnWidth> parseColumnWidths(Element htmlTable, int maxCols) {
        List<ColumnWidth> columnWidths = new ArrayList<>(maxCols);

        // 初始化所有列宽为自动
        for (int i = 0; i < maxCols; i++) {
            columnWidths.add(new ColumnWidth(0, TableWidthType.AUTO));
        }

        // 1. 优先从colgroup/col标签获取列宽
        Element colgroup = htmlTable.selectFirst("colgroup");
        if (colgroup != null) {
            Elements cols = colgroup.select("col");
            int colIdx = 0;
            for (Element col : cols) {
                if (colIdx >= maxCols) break;

                String width = col.attr("width");
                if (!width.isEmpty()) {
                    ColumnWidth cw = parseWidthValue(width);
                    columnWidths.set(colIdx, cw);
                }

                colIdx++;
            }
        }

        // 2. 从第一行单元格获取列宽（如果没有col标签）
        if (colgroup == null || colgroup.children().size() == 0) {
            Element firstRow = htmlTable.selectFirst("tr");
            if (firstRow != null) {
                Elements cells = firstRow.select("td, th");
                int colIdx = 0;

                for (Element cell : cells) {
                    if (colIdx >= maxCols) break;

                    String width = cell.attr("width");
                    if (StringUtils.isBlank(width)) {
                        Map<String, String> styles = parseStyles(cell);
                        width = styles.get("width");
                    }

                    if (StringUtils.isNotBlank(width)) {
                        int colspan = getIntAttribute(cell, "colspan", 1);
                        ColumnWidth cw = parseWidthValue(width);

                        // 处理跨列情况：平均分配宽度
                        if (colspan > 1) {
                            for (int i = 0; i < colspan; i++) {
                                if (colIdx + i < maxCols) {
                                    columnWidths.set(colIdx + i, cw);
                                }
                            }
                            colIdx += colspan;
                        } else {
                            columnWidths.set(colIdx, cw);
                            colIdx++;
                        }
                    } else {
                        colIdx++;
                    }
                }
            }
        }

        // 3. 处理表格整体宽度为固定值的情况
        String tableWidth = htmlTable.attr("width");
        if (tableWidth.isEmpty()) {
            Map<String, String> tableStyles = parseStyles(htmlTable);
            tableWidth = tableStyles.getOrDefault("width", "");
        }

        if (!tableWidth.isEmpty() && !tableWidth.endsWith("%")) {
            // 表格有固定宽度，计算每列的绝对宽度
            int totalTableWidth = parseWidthToTwips(tableWidth);
            int totalColWidth = 0;
            int autoCols = 0;

            // 计算已设置宽度的列的总宽度和自动列的数量
            for (ColumnWidth cw : columnWidths) {
                if (cw.type == TableWidthType.DXA) {
                    totalColWidth += cw.width;
                } else {
                    autoCols++;
                }
            }

            // 为自动列分配剩余宽度
            if (autoCols > 0 && totalColWidth < totalTableWidth) {
                int remainingWidth = totalTableWidth - totalColWidth;
                int autoColWidth = remainingWidth / autoCols;

                for (int i = 0; i < columnWidths.size(); i++) {
                    ColumnWidth cw = columnWidths.get(i);
                    if (cw.type == TableWidthType.AUTO) {
                        columnWidths.set(i, new ColumnWidth(autoColWidth, TableWidthType.DXA));
                    }
                }
            }
        }

        return columnWidths;
    }

    private static ColumnWidth parseWidthValue(String width) {
        if (width.endsWith("%")) {
            try {
                int percent = Integer.parseInt(width.substring(0, width.length() - 1));
                return new ColumnWidth(percent, TableWidthType.PCT);
            } catch (NumberFormatException e) {
                return new ColumnWidth(0, TableWidthType.AUTO);
            }
        } else {
            int twips = parseWidthToTwips(width);
            return twips > 0 ?
                    new ColumnWidth(twips, TableWidthType.DXA) :
                    new ColumnWidth(0, TableWidthType.AUTO);
        }
    }

    private static int parseWidthToTwips(String width) {
        // 移除单位，尝试解析为数字
        width = width.replaceAll("[^\\d.]", "");
        if (width.isEmpty()) return 0;

        try {
            double value = Double.parseDouble(width);
            // 将像素或点转换为twips (1twip = 1/20点，1英寸=72点=1440twips)
            return (int) Math.round(value * 20);
        } catch (NumberFormatException e) {
            return 0;
        }
    }

    private static void applyColumnWidths(XWPFTable table, List<ColumnWidth> columnWidths) {
        // 确保表格有足够的列
        while (table.getRow(0).getTableCells().size() < columnWidths.size()) {
            table.getRow(0).addNewTableCell();
        }

        // 应用列宽设置
        for (int i = 0; i < columnWidths.size(); i++) {
            ColumnWidth cw = columnWidths.get(i);
            XWPFTableCell cell = table.getRow(0).getCell(i);
            if (cw.type == TableWidthType.PCT) {
                cell.setWidthType(TableWidthType.PCT);
                cell.setWidth(String.valueOf(cw.width));
            } else if (cw.type == TableWidthType.DXA && cw.width > 0) {
                cell.setWidthType(TableWidthType.DXA);
                cell.setWidth(String.valueOf(cw.width));
            } else {
                cell.setWidthType(TableWidthType.AUTO);
                cell.setWidth("0");
            }
        }
    }

    private static void processCell(Element htmlCell, XWPFTableCell tableCell, int colspan, int rowspan) {
        // 解析单元格样式
        Map<String, String> cellStyles = parseStyles(htmlCell);

        // 设置单元格文本内容
        String cellText = htmlCell.text();
        XWPFParagraph paragraph = tableCell.getParagraphs().size() > 0
                ? tableCell.getParagraphs().get(0)
                : tableCell.addParagraph();
        XWPFRun run = paragraph.createRun();
        run.setText(cellText);
        run.setFontSize(12);
        run.setFontFamily("宋体");
        // 应用单元格样式
        applyCellStyle(tableCell, cellStyles);

        // 如果是表头单元格，设置为粗体
//        if ("th".equalsIgnoreCase(htmlCell.tagName())) {
//            run.setBold(true);
//        }
    }

    private static void setCellMerging(XWPFTable table, int rowIdx, int colIdx, int rowspan, int colspan) {
        // 处理跨行合并
        if (rowspan > 1) {
            // 设置当前单元格为开始合并
            table.getRow(rowIdx).getCell(colIdx).getCTTc().addNewTcPr().addNewVMerge().setVal(STMerge.RESTART);

            // 设置后续单元格为继续合并
            for (int i = 1; i < rowspan; i++) {
                if (rowIdx + i < table.getRows().size()) {
                    table.getRow(rowIdx + i).getCell(colIdx).getCTTc().addNewTcPr().addNewVMerge().setVal(STMerge.CONTINUE);
                }
            }
        }

        // 处理跨列合并
        if (colspan > 1) {
            // 设置当前单元格为开始合并
            table.getRow(rowIdx).getCell(colIdx).getCTTc().addNewTcPr().addNewGridSpan().setVal(BigInteger.valueOf(colspan));
        }
    }

    private static Map<String, String> parseStyles(Element element) {
        Map<String, String> styles = new HashMap<>();
        String styleAttr = element.attr("style");

        if (!styleAttr.isEmpty()) {
            String[] declarations = styleAttr.split(";");
            for (String declaration : declarations) {
                String[] parts = declaration.split(":", 2);
                if (parts.length == 2) {
                    styles.put(parts[0].trim(), parts[1].trim());
                }
            }
        }

        return styles;
    }

    private static void applyTableStyle(XWPFTable table, Map<String, String> styles) {
        // 设置表格宽度
        String width = styles.get("width");
        if (width != null) {
            if (width.endsWith("%")) {
                table.setWidth(width.replace("%", ""));
                table.setWidthType(TableWidthType.PCT);
            } else if (width.matches("\\d+")) {
                table.setWidth(width);
                table.setWidthType(TableWidthType.DXA);
            }
        }

        // 设置边框
        if (styles.containsKey("border") || styles.containsKey("border-width")) {
            int borderSize = 8; // 默认8分之1磅
            if (styles.containsKey("border-width")) {
                String borderWidth = styles.get("border-width");
                if (borderWidth.matches("\\d+(\\.\\d+)?")) {
                    borderSize = (int) (Float.parseFloat(borderWidth) * 8);
                }
            }

            CTTblBorders borders = table.getCTTbl().getTblPr().addNewTblBorders();
            setBorder(borders.addNewTop(), borderSize, styles.get("border-color"));
            setBorder(borders.addNewBottom(), borderSize, styles.get("border-color"));
            setBorder(borders.addNewLeft(), borderSize, styles.get("border-color"));
            setBorder(borders.addNewRight(), borderSize, styles.get("border-color"));
            setBorder(borders.addNewInsideH(), borderSize, styles.get("border-color"));
            setBorder(borders.addNewInsideV(), borderSize, styles.get("border-color"));
        }
    }

    private static void setBorder(CTBorder border, int size, String color) {
        border.setSz(BigInteger.valueOf(size));
        border.setColor(color != null ? color.replace("#", "") : "000000");
        border.setVal(STBorder.SINGLE);
    }

    private static void applyRowStyle(XWPFTableRow row, Map<String, String> styles) {
        // 设置行高
        String height = styles.get("height");
        if (height != null && height.matches("\\d+(\\.\\d+)?")) {
            row.setHeight((int) (Float.parseFloat(height) * 20)); // 转换为twips
        }
    }

    private static void applyCellStyle(XWPFTableCell cell, Map<String, String> styles) {
        // 设置单元格背景色
        String backgroundColor = styles.get("background-color");
        if (backgroundColor != null && backgroundColor.matches("#[0-9a-fA-F]{6}")) {
            cell.setColor(backgroundColor.replace("#", ""));
        }

        // 设置单元格文本对齐方式
        String textAlign = styles.get("text-align");
        String verticalAlign = styles.get("vertical-align");

        // 水平对齐
        ParagraphAlignment hAlign = ParagraphAlignment.CENTER;
        if ("center".equalsIgnoreCase(textAlign)) {
            hAlign = ParagraphAlignment.CENTER;
        } else if ("right".equalsIgnoreCase(textAlign)) {
            hAlign = ParagraphAlignment.RIGHT;
        } else if ("justify".equalsIgnoreCase(textAlign)) {
            hAlign = ParagraphAlignment.BOTH;
        }

        // 垂直对齐
        XWPFTableCell.XWPFVertAlign vAlign = XWPFTableCell.XWPFVertAlign.CENTER;
        if ("middle".equalsIgnoreCase(verticalAlign)) {
            vAlign = XWPFTableCell.XWPFVertAlign.CENTER;
        } else if ("bottom".equalsIgnoreCase(verticalAlign)) {
            vAlign = XWPFTableCell.XWPFVertAlign.BOTTOM;
        }

        // 应用对齐方式
        for (XWPFParagraph para : cell.getParagraphs()) {
            para.setAlignment(hAlign);
        }
        cell.setVerticalAlignment(vAlign);

        // 设置单元格边距
        String padding = styles.get("padding");
        if (padding != null) {
            int paddingValue = parsePaddingValue(padding);
            if (paddingValue > 0) {
                CTTcPr tcPr = cell.getCTTc().addNewTcPr();
                CTTcMar cellMargin = tcPr.addNewTcMar();
                cellMargin.addNewLeft().setW(paddingValue);
                cellMargin.addNewRight().setW(paddingValue);
                cellMargin.addNewTop().setW(paddingValue);
                cellMargin.addNewBottom().setW(paddingValue);
            }
        }
    }

    private static int parsePaddingValue(String padding) {
        // 简单处理，假设padding是一个数字+单位（如"10px"）
        Pattern pattern = Pattern.compile("(\\d+)(px|pt)?");
        Matcher matcher = pattern.matcher(padding);

        if (matcher.find()) {
            int value = Integer.parseInt(matcher.group(1));
            // 将px或pt转换为twips（1twip = 1/20点）
            return value * 20;
        }

        return 0;
    }

    private static int getIntAttribute(Element element, String attribute, int defaultValue) {
        String value = element.attr(attribute);
        if (value.isEmpty()) {
            return defaultValue;
        }

        try {
            return Integer.parseInt(value);
        } catch (NumberFormatException e) {
            return defaultValue;
        }
    }

    // 列宽数据类
    static class ColumnWidth {
        int width;
        TableWidthType type;

        public ColumnWidth(int width, TableWidthType type) {
            this.width = width;
            this.type = type;
        }
    }

    /**************************添加页码*********************************/
    private static void createPageNumberFooter(XWPFDocument document, CTSectPr sectPr) {
        XWPFFooter footer = document.createFooter(HeaderFooterType.DEFAULT);//创建一个新的XWPFFooter对象
        XWPFParagraph paragraph = footer.createParagraph();//创建新的XWPFParagraph对象
        paragraph.setAlignment(ParagraphAlignment.CENTER);//设置样式居中
        //设置段落对象
        XWPFRun runPre = paragraph.createRun();//新的段落对象
        runPre.setText("第 ");
        setXWPFRunStyle(runPre,"宋体", 12);
        XWPFRun run = paragraph.createRun();//新的段落对象
        CTFldChar fldChar = run.getCTR().addNewFldChar();//新的CTFldChar对象
        fldChar.setFldCharType(STFldCharType.Enum.forString("begin"));
        CTText ctText = run.getCTR().addNewInstrText();
        ctText.setStringValue("PAGE  \\* MERGEFORMAT");
        ctText.setSpace(SpaceAttribute.Space.Enum.forString("preserve"));
        setXWPFRunStyle(run,"宋体",12);
        fldChar = run.getCTR().addNewFldChar();
        fldChar.setFldCharType(STFldCharType.Enum.forString("end"));
        //设置段落对象
        XWPFRun runSuf = paragraph.createRun();//新的段落对象
        runSuf.setText(" 页");
        setXWPFRunStyle(runSuf,"宋体",12);
        // 将页脚添加到所有的页面
        XWPFHeaderFooterPolicy headerFooterPolicy = new XWPFHeaderFooterPolicy(document);
        headerFooterPolicy.createFooter(STHdrFtr.DEFAULT, new XWPFParagraph[]{paragraph});
    }
    /**
     * 设置页脚的字体样式
     * @param xr 段落元素
     * @param font 段落元素
     * @param fontSize 的大小
     */
    static void setXWPFRunStyle(XWPFRun xr, String font, int fontSize) {
        xr.setFontSize(fontSize);
        xr.setFontFamily(font);
    }
}
